/** 
 * @file translator.cpp
 * @Synopsis  the main program file
 * @author Kumar Anik
 * @version 1.0
 * @date 2010-06-25
 */
#include "svg.h"
#include "animation.h"

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>

void process(string str);
string inputPoly(int n, bool draw);
string inputEllipse(int n, bool draw);
string inputPath(bool draw);
string inputAnimation();

ofstream fout("1.svg");

int main()
{
	string input;

	fout << insertSvgHeader();                                    ///insert svg header

	while ( 1 )						      ///Keep taking commands			
	{
		cout << "\n$";
		getline( cin, input, '\n');
		if(input == "exit") {
		       break;
		} else {
	 		process(input);
		}
	}

	fout << insertSvgFooter();				      ///insert svg footer
	cout << "SVG generated, check out 1.svg!!!\n";
	return 0;
}


/** 
 * @Synopsis  process a command - draw or exit
 * 
 * @Param str : the given command
 */
void process ( string str )
{
	stringstream s;
	string token1, token2, token;
	int x1, y1, x2, y2;

	s << str;
	s >> token1;
	if(token1[0] == '#') {
		getline(s, token1, '\n');
	} 
	else if (token1 == "draw")
	{
		s >> token2;
		if ( token2 == "line" )
		{
			inputPoly(2, true);
		}
		else if (token2 == "triangle" || token2 == "tria")
		{
			inputPoly(3, true);
		}
		else if (token2 == "quadrilateral" || token2 == "quad")
		{
			inputPoly(4, true);
		}
		else if (token2 == "polygon" || token2 == "poly")
		{
			inputPoly(0, true);
		}
		else if (token2 == "circle" || token2 == "circ")
		{
			inputEllipse(1, true);
		}
		else if (token2 == "ellipse" || token2 == "elli")
		{
			inputEllipse(2, true);
		}
		else if (token2 == "path")
		{
			inputPath(true);
		}
		else if (token2 == "animation")
		{
			inputAnimation();
		}
		else
		{
			cout << " want to draw what??";
		}
	}
	else
	{
		cout << "What???\n";
	}
}


/** 
 * @Synopsis  input interaction for  a polgon
 * 
 * @Param n number of sides, 0 for variable
 * @Param draw whether to draw or not
 * 
 * @Returns   the SVG code of the polygon
 */
string inputPoly( int n, bool draw )
{
	char ch;
	string str;
	Polygon p;
	bool animated;
	int i, x, y, x1, x2, y1, y2;

	if ( !n )
	{
		cout << "Enter the number of edges : ";
		cin >> n;
	}

	cout << "Enter the required values ( -1 to animate ) : ";

	animated = false;			 /// just a flag to see whether animated or not

	for (i = 0; i < n; i++ )
	{
		cout << "\nEnter x" << i << " : ";
		cin >> x;
		if(x == -1)
		{
			animated = true;
			cout << "\tEnter initial value : ";
			cin >> x1;
			cout << "\tEnter Final value : ";
			cin >> x2;
		}

		cout << "Enter y" << i << " : ";
		cin >> y;

		if(y == -1)
		{
			animated = true;
			cout << "\tEnter initial value : ";
			cin >> y1;
			cout << "\tEnter Final value : ";
			cin >> y2;
		}

		if(x == -1 && y == -1)
		{
			p.addAnimation(x1, y1, x2, y2);
		}
		else if (x == -1)
		{
			p.addAnimation(x1, y, x2, y);
		}
		else if (y == -1)
		{
			p.addAnimation(x, y1, x, y2);
		}
		else
		{
			p.addPoint(x, y);
		}
	}

	cout << "Enter other options (y/n) : ";
	cin >> ch;

	if( ch == 'y' || ch == 'Y')
	{
		cout << "Enter the values (enter -1 for default)\n";

		cout << "Enter color, e.g green, magenta : ";
		cin >> str;

		if(str != "-1")
		{
			p.color = str;
		}

		if(n > 2)
		{
			cout << "Enter the fill color, e.g. green, magenta : ";
			cin >> str;

			if(str != "-1")
			{
				p.fillColor = str;
			}
		}

		cout << "Enter width of pen (1-10) : ";
		cin >> x;

		if ( x != -1)
			p.width = x;

		if ( animated )
		{
			cout << "Enter duration of animation in sec :";
			cin >> x;

			if ( x != -1 )
			{
				p.dur = x;
			}

			cout << "Number of times animation repeats "
				<< "(default: indefinite) :";
			cin >> str;

			if ( str != "-1" )
			{
				p.repeatCount = str;
			}

		}

	}

	str = p.draw();

	if(draw)
	{
		fout << str;
	}

	return str;
}


/** 
 * @Synopsis  input interaction for an Ellipse
 * 
 * @Param n number of different radii ( 1/2 )
 * @Param draw whether to draw or not
 * 
 * @Returns   the SVG code for the Ellipse
 */
string inputEllipse(int n, bool draw)
{
	int x;
	char ch;
	string str;
	int i, cx, cy, r[2];
	bool animated;

	cout << "Enter x co-ordinate for center : ";
	cin >> cx;
	cout << "Enter y co-ordinate for center : ";
	cin >> cy;

	for( i = 0; i < n; i++ )
	{
		cout << "Enter radius "<< (char)('x' + i) << " : ";
		cin >> r[i];
	}

	if(n == 1)
		r[1] = r[0];

	Ellipse p(cx, cy, r[0], r[1]);

	cout << "Enter other options (y/n) : ";
	cin >> ch;

	if( ch == 'y' || ch == 'Y')
	{
		cout << "Enter the values (enter -1 for default)\n";

		cout << "Enter color, e.g green, magenta : ";
		cin >> str;

		if(str != "-1")
		{
			p.color = str;
		}

		cout << "Enter the fill color, e.g. green, magenta : ";
		cin >> str;

		if(str != "-1")
		{
			p.fillColor = str;
		}

		cout << "Enter width of pen (1-10) : ";
		cin >> x;

		if ( x != -1)
			p.width = x;
	}

	str = p.draw();

	if(draw)
	{
		fout << str;
	}

	return str;

}


/** 
 * @Synopsis  input interaction for a path
 * 
 * @Param draw whether to draw or not
 * 
 * @Returns   the SVG code for the path
 */
string inputPath(bool draw)
{
	int x, y, x1, y1, x2, y2;
	char ch = '1', ch2;
	string str;
	bool flag = true, flag1, flag2;
	Path P;
	P.addMoveTo(false, 0, 0);

	cout << "Initially the path starts at (0,0), If you want to start from somewhere else,"
		<< " use \"Move to\" first!\n";

	while(ch != '8')
	{
		cout << "\n\n***********\n\n";
		cout << "From the current position (x0, y0), \n";
		cout << "\t1. Move to (x, y)\n";
		cout << "\t2. Line to (x, y)\n";
		cout << "\t3. Horizontal Line to (x, y0)\n";
		cout << "\t4. Vertical Line to (x0, y)\n";
		cout << "\t5. Cubic Curve to (x, y) using (x1, y1) and (x2, y2) as control points\n";
		cout << "\t6. Quadratic Curve to (x, y) using (x1, y1) as control point\n";
		cout << "\t7. Elliptical Arc to (x, y) using rx, ry, xRot,and flags viz. large-arc and sweep\n";
		cout << "\t8. Enough!!\n";
		cout << "  Select (1-8) ";
		cin >> ch;

		if(ch != '8')
		{
			cout << "Do you want to enter absolute co-ordinates (y/n)? (y:Absolute, n:Relative) :";
			cin >> ch2;

			flag = ((ch2 == 'n') ? true:false);
		}

		switch(ch)
		{
			case '1':
				cout << "\tEnter x : ";
				cin >> x;
				cout << "\tEnter y : ";
				cin >> y;

				P.addMoveTo(flag, x,y);
				break;
			case '2':
				cout << "\tEnter x : ";
				cin >> x;
				cout << "\tEnter y : ";
				cin >> y;

				P.addLineTo(flag, x,y);
				break;
			case '3':
				cout << "\tEnter x : ";
				cin >> x;

				P.addHorizontalLineTo(flag, x);
				break;
			case '4':
				cout << "\tEnter y : ";
				cin >> y;

				P.addVerticalLineTo(flag, y);
				break;
			case '5':
				cout << "\tEnter x : ";
				cin >> x;
				cout << "\tEnter y : ";
				cin >> y;
				cout << "\tEnter x1 : ";
				cin >> x1;
				cout << "\tEnter y1 : ";
				cin >> y1;
				cout << "\tEnter x2 : ";
				cin >> x2;
				cout << "\tEnter y2 : ";
				cin >> y2;

				P.addCurveTo(flag, x1, y1, x2, y2, x, y);
				break;
			case '6':
				cout << "\tEnter x : ";
				cin >> x;
				cout << "\tEnter y : ";
				cin >> y;
				cout << "\tEnter x1 : ";
				cin >> x1;
				cout << "\tEnter y1 : ";
				cin >> y1;

				P.addQuadCurveTo(flag, x1, y1, x, y);
				break;
				break;
			case '7':
				cout << "\tEnter rx : ";
				cin >> x1;
				cout << "\tEnter ry : ";
				cin >> y1;
				cout << "\tEnter xRot : ";
				cin >> x2;
				cout << "\tEnter large-arc-flag (0/1) : ";
				cin >> flag1;
				cout << "\tEnter sweep-flag (0/1) : ";
				cin >> flag2;
				cout << "\tEnter x : ";
				cin >> x;
				cout << "\tEnter y : ";
				cin >> y;

				P.addEllipticalArcTo(flag, x1, y1, x2, flag1, flag2, x, y);
				break;
			default:
				cout << "Path definition compelete!\n***********\n\n";
				break;
		};

	}

	cout << "Return to origin (y/n) : ";
	cin >> ch2;

	if(ch2 == 'y')
		P.returnToInitial();

	cout << "Enter other options (y/n) : ";
	cin >> ch;

	if( ch == 'y' || ch == 'Y')
	{
		cout << "Enter the values (enter -1 for default)\n";

		cout << "Enter color, e.g green, magenta : ";
		cin >> str;

		if(str != "-1")
		{
			P.color = str;
		}

		if(ch2 == 'y')
		{
			cout << "Enter the fill color, e.g. green, magenta : ";
			cin >> str;

			if(str != "-1")
			{
				P.fillColor = str;
			}
		}

		cout << "Enter width of pen (1-10) : ";
		cin >> x;

		if ( x != -1)
			P.width = x;
	}

	if(draw)
	{
		fout << P.draw();
	}

	return P.returnPath();
}


/** 
 * @Synopsis  input interaction for the animation
 * 
 * @Returns   the SVG code of the animation
 */
string inputAnimation()
{
	int ch=0;
	int dur; 
	string str;
	Animation A;
	AnimateMotion AM;

	while (ch != 6)
	{

		cout << "\n\nCreating an animation..\n";
		cout << "\tEnter the choice to be entered in the group\n";
		cout << "\t1. Add a polygon.\n";
		cout << "\t2. Add a circle. \n";
		cout << "\t3. Add an arc.\n";
		cout << "\t4. Add a Path Animation.\n";
		cout << "\t5. Add a Transform Animation.\n";
		cout << "\t6. Enough!!\n";
		cout << "\t Enter your choice (1-6) : ";

		cin >> ch;

		switch ( ch )
		{
			case 1:
				str = inputPoly(0, false);
				A.add(str);

				break;
			case 2:
				str = inputEllipse(1, false);
				A.add(str);

				break;
			case 3:
				str = inputPath(false);
				A.add(str);

				break;
			case 4:
				cout << "***********************\n\nOK, so describe the path on which your group will move!\n";
				str = inputPath( false);

				cout << "Enter the duration for animation : ";
				cin >> dur;
				
				AM.path = str;
				AM.dur = dur;

				A.add(AM.draw());

				break;
			default:
				cout << "Animation definition Complete\n";

		};
	
	}

	str = A.draw();

	if(1) {
		fout << str;
	}

	return str;


}
